﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.SharePoint.Administration;
using Microsoft.SharePoint.Administration.Health;
using Microsoft.SharePoint.Utilities;
using Microsoft.Office.Server.Search.Administration;

namespace SPHealth.SharePoint.HealthRules.SP.Rules.Performance
{
    public class WarnIndexLocation : SPHealthAnalysisRule
    {
        #region Locals
        private string sharepointdriveletter = "";
        private string results = "";
        #endregion

        #region Constructor
        /* This rules does not require a constructor */
        #endregion

        #region Fields

        // the category to display this rule under
        public override SPHealthCategory Category
        {
            get { return SPHealthCategory.Performance; }
        }

        // the type or error to flag this rule as
        public override SPHealthCheckErrorLevel ErrorLevel
        {
            get { return SPHealthCheckErrorLevel.Warning; }
        }

        // the Explanation for the rule and what is not working
        public override string Explanation
        {
            get { return string.Format("Ideally the Search Index should be written to a separate physical disk to improve system performance and throughput. SharePoint is deployed to the {0}: drive, the Search Index is written to the following location(s):\r\n\r\n{1}", sharepointdriveletter, results); }
        }

        // how to fix the issue
        public override string Remedy
        {
            get { return "Assign the Search Index to use a different physical hard disk than the one used by the SharePoint installation."; }
        }

        // the Summary for the rule
        public override string Summary
        {
            get { return "The Search Index should not be written to the same physical disk that SharePoint is installed on."; }
        }

        public override SPHealthAnalysisRuleAutomaticExecutionParameters AutomaticExecutionParameters
        {
            get
            {
                SPHealthAnalysisRuleAutomaticExecutionParameters retval = new SPHealthAnalysisRuleAutomaticExecutionParameters();
                retval.Schedule = SPHealthCheckSchedule.Daily;
                retval.Scope = SPHealthCheckScope.All;
                retval.ServiceType = typeof(SPTimerService);
                return retval;
            }
        }
        #endregion

        #region Methods

        // this method is called whenever the rule is executed
        public override SPHealthCheckStatus Check()
        {
            if (!SPFarm.Joined)
                throw new InvalidOperationException();

            // setup
            string sharepointlocation = SPUtility.GetGenericSetupPath("");
            sharepointlocation = common.ReplaceEnvironmentVariables(sharepointlocation);
            sharepointdriveletter = sharepointlocation.Substring(0, 1).ToLower();
            results = "";

            // get our (local) search service
            SearchService service = SPFarm.Local.Services.GetValue<SearchService>("OSearch14");

            if (service != null)
            {
                // get our search service applications
                foreach (SPServiceApplication searchApp in service.SearchApplications)
                {
                    SearchServiceApplication searchServiceApp = searchApp as SearchServiceApplication;
                    if (searchServiceApp != null)
                    {
                        // get our crawler compontents
                        foreach (CrawlComponent crawler in searchServiceApp.CrawlTopologies.ActiveTopology.CrawlComponents)
                        {
                            // does our index location exist on the same disk as sharepoint?
                            string crawlerLocation = crawler.IndexLocation;
                            crawlerLocation = common.ReplaceEnvironmentVariables(crawlerLocation).ToLower();
                            if (crawlerLocation.StartsWith(sharepointdriveletter))
                            {
                                // we've got an index that ought to be moved...
                                results += string.Format("{0} - {1}\r\n\r\n", searchServiceApp.Name, crawler.IndexLocation);
                            }
                        }
                    }
                }
            }

            // determine is the check has passed or failed.
            if (!string.IsNullOrEmpty(results))
                return SPHealthCheckStatus.Failed;
            else
                return SPHealthCheckStatus.Passed;
        }

        #endregion

    }
}
